/*
 * Fichier source C++ du projet menulib
 *
 * Cible : PSP
 * Auteur : BuLLeKeUp
 * Date de création : 18/03/2012
 * Date de dernière modification : 18/03/2012
 *
 * Ce projet est sous license GNU GPL v3. Consultez la license associée dans le repertoire doc/gplv3.txt
 * ou rendez vous sur http://www.gnu.org/copyleft/gpl.html
 *
 * Nom du fichier : main.cpp
 *
 * Description : Classe permettant la création d'un menu pour affichage
 *
 */

#include "menu.h"

/*
 * Class constructors
 */
menu::menu() {
    this->titles = NULL;
    this->backgroundColor = ColorBlack;
    this->nbTitles = 0;
    this->headerTitle = NULL;
    
}

menu::menu(titleOptions* p_titles, int p_nbTitles, char *p_headerTitle) {
    if((p_titles != NULL) && (p_nbTitles > 0) && (p_headerTitle != NULL)) {
        this->titles = p_titles;
        this->nbTitles = p_nbTitles;
        this->headerTitle = p_headerTitle;
        this->backgroundColor = ColorBlack;
        
    }
    // Initialiser l'écran
    this->initScreen();
}

menu::menu(titleOptions* p_titles, int p_nbTitles, char* p_headerTitle, u32 p_backgroundColor) {
    if((p_titles != NULL) && (p_nbTitles > 0) && (p_headerTitle != NULL)) {
        this->titles = p_titles;
        this->nbTitles = p_nbTitles;
        this->headerTitle = p_headerTitle;
        this->backgroundColor = p_backgroundColor;
    }
    // Initialiser l'écran
    this->initScreen();
}

menu::menu(const menu& orig) {
    this->backgroundColor = orig.backgroundColor;
    this->nbTitles = orig.nbTitles;
    this->titles = orig.titles;
    
    //Initialiser l'écran
    this->initScreen();
}

/*
 * Initialize the debug screen and the different variables
 */
int menu::initScreen() {
    int i;
    
    for(i=0; i<68; i++)
        separateLine[i] = '-';
    separateLine[68] = '\0';
    
    this->cursor[0] = '=';
    this->cursor[1] = '>';
    this->cursor[2] = '\0';
    
    this->titleSelected = 0;
    this->optionSelected = 0;
    
    //this->createButtonThread();
    
    return EXIT_SUCCESS;
}

/*
 * Print the header of the menu on the screen
 */
int menu::printHeader() {
    int headerSize = strlen((const char *)this->headerTitle)/2;
    
    pspDebugScreenSetXY(0, 1);
    pspDebugScreenSetTextColor(ColorGreen);
    pspDebugScreenPuts((const char *)separateLine);
    pspDebugScreenSetXY(33-headerSize, 3);
    pspDebugScreenPuts((const char *)this->headerTitle);
    pspDebugScreenSetXY(0, 5);
    pspDebugScreenPuts((const char *)separateLine);
    
    return EXIT_SUCCESS;
}

/*
 * Print the menu on the screen
 */
int menu::printMenu() {
    int i;
    int line = 7;
    
    pspDebugScreenClear();
    this->printHeader();
    
    for(i=0; i<this->nbTitles; i++)
        this->printTitle(i, &line);
    
    return EXIT_SUCCESS;
}

/*
 * Print a title on the screen
 */
int menu::printTitle(int p_titleNb, int *p_currentLine) {
    
    int i = 0;
    int titleSize = strlen((const char *)this->titles[p_titleNb].title);
    
    switch(this->titles[p_titleNb].titlePos){
        case PosLeft :
            pspDebugScreenSetXY(4, *p_currentLine);
            break;
        case PosCenter :
            pspDebugScreenSetXY(33-(titleSize/2), *p_currentLine);
            break;
        case PosRight :
            pspDebugScreenSetXY(68-titleSize, *p_currentLine);
            break;
        default :
            pspDebugScreenSetXY(4, *p_currentLine);
            break;
    }
    
    pspDebugScreenSetTextColor(this->titles[p_titleNb].titleColor);
    pspDebugScreenPuts((const char *)this->titles[p_titleNb].title);
    (*p_currentLine) += 2;
    
    pspDebugScreenSetTextColor(this->titles[p_titleNb].optionColor);
    
    for(i=0; i<this->titles[p_titleNb].nbOptions; i++){
        if((this->titleSelected == p_titleNb) && (this->optionSelected == i)){
            this->drawCursor(*p_currentLine);
            pspDebugScreenSetTextColor(this->titles[p_titleNb].optionColor);
        }
        pspDebugScreenSetXY(7, *p_currentLine);
        pspDebugScreenPuts((const char *)this->titles[p_titleNb].options[i]);
        (*p_currentLine)++;
    }
    
    (*p_currentLine)++;
    
    return EXIT_SUCCESS;
}

/*
 * Change the background of the menu
 */
int menu::setBackgroundColor(u32 p_backgroundColor) {
    this->backgroundColor = p_backgroundColor;
    return EXIT_SUCCESS;
}

/*
 * Change the options color of the desired title
 */
int menu::setOptionsColor(int p_titleNb, u32 p_optionColor) {
    if((p_titleNb >= 0) && (p_titleNb <= this->nbTitles))
        this->titles[p_titleNb].optionColor = p_optionColor;
    return EXIT_SUCCESS;
}

/*
 * Change the color of the desired title
 */
int menu::setTitleColor(int p_titleNb, u32 p_titleColor) {
    if((p_titleNb >= 0) && (p_titleNb <= this->nbTitles))
        this->titles[p_titleNb].titleColor = p_titleColor;
    return EXIT_SUCCESS;
}

int menu::printValues() {
    pspDebugScreenClear();
    pspDebugScreenPrintf("Titre selectionne : %d", this->titleSelected);
    pspDebugScreenPrintf("Option selectionnee : %d", this->optionSelected);
    return EXIT_SUCCESS;
}

int menu::gotoOption() {
    receptFromMenu(this->titleSelected, this->optionSelected, NULL);
    return EXIT_SUCCESS;
}

int menu::terminateButtonThread() {
    if(this->buttonThreadID > 0)
        return sceKernelTerminateDeleteThread(this->buttonThreadID);
    else
        return EXIT_FAILURE;
}

int menu::drawCursor(int p_line) {
    pspDebugScreenSetXY(2, p_line);
    pspDebugScreenSetTextColor(ColorRed);
    pspDebugScreenPuts(this->cursor);
    
    return EXIT_SUCCESS;
}

int menu::getOptionSelected() {
    return this->optionSelected;
}

int menu::getTitleSelected() {
    return this->titleSelected;
}

titleOptions* menu::getTitles() {
    return this->titles;
}

int menu::getNbTitles() {
    return this->nbTitles;
}

int menu::setOptionSelected(int p_optionSelected) {
    this->optionSelected = p_optionSelected;
    return EXIT_SUCCESS;
}

int menu::setTitleSelected(int p_titleSelected) {
    this->titleSelected = p_titleSelected;
    return EXIT_SUCCESS;
}

menu::~menu() {
    if(this->headerTitle != NULL)
        delete this->headerTitle;
    this->terminateButtonThread();
}

